package lumis.portal.sendmail.dao.hibernate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lumis.portal.PortalContext;
import lumis.portal.sendmail.IMailAttachment;
import lumis.portal.sendmail.IMailBody;

/**
 * Implementation of {@link IMailBody} used by {@link SendMailDaoHib}.
 * 
 * @version $Revision: 11804 $ $Date: 2010-07-29 10:06:21 -0300 (Thu, 29 Jul 2010) $
 * @since 4.0.4
 */
class MailBody implements IMailBody
{
	private String id;
	private String textMsg;
	private String htmlMsg;
	private Collection<IMailAttachment> attachments;

	public Collection<IMailAttachment> getAttachments()
	{
		if (attachments == null)
			setAttachments(new ArrayList<IMailAttachment>());
		return new SetParentCollectionWrapper<IMailAttachment>(
				attachments, new SetParentCollectionWrapper.IParentSetter<IMailAttachment>()
		{
			public void setParent(IMailAttachment bean)
			{
				((MailAttachment)bean).setMailBody(MailBody.this);
			}
		});
	}
	public void setAttachments(Collection<IMailAttachment> attachments)
	{
		this.attachments = attachments;
	}
	public String getHtmlMsg()
	{
		if(this.htmlMsg != null)
		{
			return fixHtmlMarkup(this.htmlMsg);
		}
		else
		{
			return null;
		}
	}
	public void setHtmlMsg(String htmlMsg)
	{
		this.htmlMsg = htmlMsg;
	}
	public String getId()
	{
		return id;
	}
	public void setId(String id)
	{
		this.id = id;
	}
	public String getTextMsg()
	{
		return textMsg;
	}
	public void setTextMsg(String textMsg)
	{
		this.textMsg = textMsg;
	}
	
	/**
	 * Regexp pattern used by {@link #fixHtmlMarkup(String)} to fetch the relative paths on parameters. 
	 * @since 5.6.0
	 */
	private static final Pattern PATTERN_ATTRIBS_MISC = Pattern.compile(
			"((?:src|background|action|href)\\s*=\\s*(?:\"|'|\\\\\"|\\\\'))(?!\\s*https?:|\\s*javascript:|\\s*news:|\\s*ftp:|\\s*file:|#|mailto:|\\\\\\\\)([^'\"\\\\]+)");
	/**
	 * Regexp pattern used by {@link #fixHtmlMarkup(String)} to fetch the relative paths on background HTML codes. 
	 * @since 5.6.0
	 */
	private static final Pattern PATTERN_BACKGROUND_URL = Pattern.compile(
			"(background:url\\()(?!https?:)");
	/**
	 * Regexp pattern used by {@link #fixHtmlMarkup(String)} to fetch the relative paths on javascript codes. 
	 * @since 5.6.0
	 */
	private static final Pattern PATTERN_JAVASCRIPT_MISC = Pattern.compile(
			"((location\\.replace|location\\.assign|window\\.open)\\s*\\(\\s*(\"|'|&quot;))(?!\\s*https?:|\\s*javascript:|\\s*news:|\\s*ftp:|\\s*file:|#|mailto:|\\\\\\\\)");
	
	/**
	 * Perform some adjustments in the e-mail's HTML message.
	 * 
	 * @param markup the markup.
	 * @return the adjusted markup.
	 * @see #getHtmlMsg()
	 * @since 5.6.0
	 */
	private String fixHtmlMarkup(String markup)
	{
		StringBuffer buf = new StringBuffer(markup.length() * 2);
		
		String prefix = PortalContext.getFrameworkUrl() + "/";
		// append the markup calling encodeURL for relative URLs
		Matcher matcher = PATTERN_ATTRIBS_MISC.matcher(markup);
		while (matcher.find())
		{
			String originalURI = matcher.group(2);
			String uri = prefix + originalURI;
			matcher.appendReplacement(buf, "$1" + uri);
		}
		matcher.appendTail(buf);
		markup = buf.toString();
		
		// transform some relative URLs in absolute URLs (directly to this producer)
		markup = PATTERN_JAVASCRIPT_MISC.matcher(markup).replaceAll("$1" + prefix);
		markup = PATTERN_BACKGROUND_URL.matcher(markup).replaceAll("$1" + prefix);
		
		return markup;
	}
}
